package com.skt.controller;

import com.skt.domain.DTO.LoginDTO;
import com.skt.domain.VO.LogoutResultVO;
import com.skt.domain.VO.UserVO;
import com.skt.exception.BusinessException;
import com.skt.service.AuthService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;

@Slf4j
@RestController
@RequestMapping("/auth")
@Validated
@RequiredArgsConstructor
@Tag(name = "用户认证接口")
public class AuthController {

    private final AuthService authService;

    @Operation(
            summary = "用户注册",
            description = "注册新用户账号。系统将校验用户名、邮箱、手机号的唯一性，并对密码进行加密存储。"
    )
    @ApiResponses({
            @ApiResponse(responseCode = "200", description = "注册成功，返回用户基本信息"),
            @ApiResponse(responseCode = "400", description = "请求参数无效（格式错误、长度不符等）"),
            @ApiResponse(responseCode = "409", description = "用户名、邮箱或手机号已被注册"),
            @ApiResponse(responseCode = "429", description = "注册频率过高，请稍后重试"),
            @ApiResponse(responseCode = "500", description = "系统内部错误")
    })
    @PostMapping("/register")
    public ResponseEntity<UserVO> register(
            @Parameter(description = "用户注册信息", required = true)
            @Valid @RequestBody LoginDTO loginDTO) {

        log.info("用户注册请求: username={}", loginDTO.getUsername());
        try {
            UserVO userVO = authService.register(loginDTO);
            log.info("用户注册成功: userId={}", userVO.getId());
            return ResponseEntity.ok(userVO);
        } catch (BusinessException e) {
            log.warn("用户注册失败: username={}, error={}", loginDTO.getUsername(), e.getMessage());
            throw e;
        }
    }


    @Operation(
            summary = "用户登录",
            description = "用户登录认证接口。支持用户名/邮箱/手机号登录，系统会进行安全风控检测和身份验证。"
    )
    @ApiResponses({
            @ApiResponse(responseCode = "200", description = "登录成功，返回用户信息和访问令牌"),
            @ApiResponse(responseCode = "400", description = "请求参数无效（用户名或密码格式错误）"),
            @ApiResponse(responseCode = "401", description = "认证失败（用户名或密码错误）"),
            @ApiResponse(responseCode = "403", description = "账户被禁用或锁定"),
            @ApiResponse(responseCode = "429", description = "登录尝试过于频繁，请稍后重试"),
            @ApiResponse(responseCode = "500", description = "系统内部错误")
    })
    @PostMapping("/login")
    public ResponseEntity<UserVO> login(
            @Parameter(description = "用户登录信息", required = true)
            @Valid @RequestBody LoginDTO loginDTO) {

        log.info("用户登录请求: username={}", loginDTO.getUsername());
        try {
            UserVO userVO = authService.login(loginDTO);
            log.info("用户登录成功: userId={}", userVO.getId());
            return ResponseEntity.ok(userVO);
        } catch (BusinessException e) {
            log.warn("用户登录失败: username={}, error={}", loginDTO.getUsername(), e.getMessage());
            throw e;
        }
    }

    @Operation(
            summary = "用户登出",
            description = "用户安全退出系统。系统将立即失效访问令牌，清理会话状态，并记录登出审计日志。"
    )
    @ApiResponses({
            @ApiResponse(responseCode = "200", description = "登出成功"),
            @ApiResponse(responseCode = "401", description = "未授权访问（令牌无效或已过期）"),
            @ApiResponse(responseCode = "429", description = "操作频率过高，请稍后重试"),
            @ApiResponse(responseCode = "500", description = "系统内部错误")
    })
    @PostMapping("/logout")
    public ResponseEntity<LogoutResultVO> logout(
            @Parameter(description = "是否登出所有设备", example = "false")
            @RequestParam(value = "logoutAllDevices", required = false, defaultValue = "false") Boolean logoutAllDevices) {

        log.info("用户登出请求: logoutAllDevices={}", logoutAllDevices);
        try {
            LogoutResultVO result = authService.logout(logoutAllDevices);
            log.info("用户登出成功: logoutAllDevices={}", logoutAllDevices);
            return ResponseEntity.ok(result);
        } catch (BusinessException e) {
            log.warn("用户登出失败: logoutAllDevices={}, error={}", logoutAllDevices, e.getMessage());
            throw e;
        }
    }


    @Operation(
            summary = "刷新访问令牌",
            description = "使用刷新令牌获取新的访问令牌。适用于访问令牌过期后无需重新登录即可续期。"
    )
    @ApiResponses({
            @ApiResponse(responseCode = "200", description = "令牌刷新成功，返回新的访问令牌和刷新令牌"),
            @ApiResponse(responseCode = "401", description = "刷新令牌无效或已过期"),
            @ApiResponse(responseCode = "403", description = "刷新令牌已被撤销或用户账户异常"),
            @ApiResponse(responseCode = "429", description = "刷新频率过高，请稍后重试"),
            @ApiResponse(responseCode = "500", description = "系统内部错误")
    })
    @PostMapping("/refresh-token")
    public ResponseEntity<UserVO> refreshToken(
            @Parameter(description = "刷新令牌", required = true)
            @RequestHeader("Refresh-Token") String refreshToken) {

        log.info("刷新令牌请求");
        try {
            UserVO userVO = authService.refreshToken(refreshToken);
            log.info("刷新令牌成功");
            return ResponseEntity.ok(userVO);
        } catch (BusinessException e) {
            log.warn("刷新令牌失败: error={}", e.getMessage());
            throw e;
        }
    }
}